#ifndef PARSER_H
#define PARSER_H

#include <fstream>
#include <map>
#include <string>
#include <list>
#include <stack>
#include <sstream>

#include "function.h"

#define BLOCK_SIZE 4096

class Parser
{        
    class LexicalAnalyzer
    {
        std::ifstream fileStream;
        char currChar;
        unsigned int id;
    
        std::stringstream stringBuf;
        
    public:
        typedef enum {Id, Equal, Semicolon, Comma, LeftPar, RightPar, None, End} Token;
        
        LexicalAnalyzer (const char* filePath);
        virtual ~LexicalAnalyzer();
        
        Token GetNextToken();
        const std::string GetTokenString();
        const char* GetTokenChars();
        
    private:    
        inline bool IsChar (char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
        inline void ReadNextChar() { fileStream >> currChar; }
        
        void SkipWhiteSpaces();
        Token Scan();
    };

    LexicalAnalyzer scanner;
    LexicalAnalyzer::Token currToken;
    
    std::map<std::string, Function*> aliases;
    std::map<std::string, std::list<Function*> > aliasDependences;
    std::stack<Function*> funcStack;
    CallGraph* graph;
    
    void Stmt();
    void Params();
    void Args();
    void List();
    void Ext();
    void Match (LexicalAnalyzer::Token t);      

public:
    Parser (const char* filePath);
    virtual ~Parser();
    
    CallGraph* Parse();
};


#endif // PARSER_H
